home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1995 October
/
EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso
/
Aminet
/
util
/
dtype
/
cdt_39_10.lha
/
cdt
/
source
/
RCS
/
dispatch.c,v
< prev
next >
Wrap
Text File
|
1995-06-04
|
20KB
|
792 lines
head 39.7;
access;
symbols
V39_10:39.7
c3910:39.7
V39_9:39.6;
locks; strict;
comment @** @;
39.7
date 95.06.04.16.47.28; author StRuppert; state Exp;
branches;
next 39.6;
39.6
date 95.05.10.15.00.37; author StRuppert; state Exp;
branches;
next ;
desc
@initial
@
39.7
log
@initialization for tabs buffer
@
text
@/*
** $PROJECT: c.datatype
**
** $VER: dispatch.c 39.7 (04.06.95)
**
** by
**
** Stefan Ruppert , Windthorststraße 5 , 65439 Flörsheim , GERMANY
**
** (C) Copyright 1995
** All Rights Reserved !
**
** $HISTORY:
**
** 04.06.95 : 039.007 : initialization for tabs buffer
** 10.05.95 : 039.006 : added userdefined types
** 14.04.95 : 039.005 : added inlined args support and template
** 01.04.95 : 039.004 : added GLOBAL template
** 23.03.95 : 039.003 : added TEXT arg, now full tabs handling
** 13.03.95 : 039.002 : autodoc completed
** 06.03.95 : 039.001 : initial
*/
/* ------------------------------- include -------------------------------- */
#include "classbase.h"
/* ------------------------------- autodoc -------------------------------- */
/*FS*/ /*"AutoDoc"*/
/*GB*** c.datatype/c.datatype ************************************************
NAME
c.datatype - data type for any c source
FUNCTION
This datatype is designed to display C and C++ source codes. It
display's different parts of the C source in different style and
color.At the moment these parts are :
STANDARD - any text which, doesn't match the following parts
COMMENT - any comment such like \* ... *\ and // ...
CPP - any C-PreProcessor keyword like "#define" or "#include"
KEYWORD - any C/C++ keyword, which isn't handled explicitly
STORAGE - extern,static,register,auto keywords
TYPES - basic type keywords like int,char,long etc.
TYPENAME - any name following a struct,union,class or enum
STRING - any string or char literal
NUMBER - any number constant decimal,hex
It uses a parser generated by bison with my yacc grammer.Because it's
a parser, it may occur a parse error on some unusual source code. If
this happens please send me a description of this parse error and
maybe the input file. So I can fix this problem !
PREFS
The c.prefs file is searched first in PROGDIR:Prefs/DataTypes/ and
then in Env:DataTypes/ with the following three ReadArgs() templates :
- CPART/A/K,PEN/N/K,R=RED/N/K,G=GREEN/N/K,B=BLUE/N/K,ITALIC/S,BOLD/S,
UNDERLINED/S,TEXT/S
CPART is one of the explaned cpart names like COMMENT or CPP.
PEN assigns the color with the pen number to the specified part
R,G,B defines a new color for the specified part. This color is
allocated with ObtainBestPenA(...,OBP_Precision,
PRECISION_ICON);
ITALIC,BOLD,UNDERLINED specifies the font style for the part
TEXT treat this CPART as normal text
- GLOBAL/A/S,TABLENGTH/N/K,NONESTEDCOMMENTS/S
GLOBAL indicates, that this line is a global setting. Note: The
/A/S combination isn't supported from ReadArgs(), so I check
it manually !
TABLENGTH - number of spaces to use for a tab !
NONESTEDCOMMENTS - disables nested comments
- INLINEARGS/A/S,KEYWORD/K/A,PATTERN/K/A,LINES/N/K
INLINEARGS indicates ,that this line is a inline args setting
KEYWORD defines the keyword to search for the inlined arguments for
the first lines. You can specify any string, which is compared
using strcmp(). After the keyword follows directly the pattern
specified by PATTERN.
PATTERN defines the pattern to get the inlined arguments. Any char
in the pattern must match the char in the text after the
keyword. To get any arguments you can specify a template using
the '%' char like in scanf() function. Following options are
supported :
%t - stands for the TABLENGTH
%c - stands for NESTEDCOMMENTS or NONESTEDCOMMENTS
LINES - specifies the number of lines from the beginning scanned
for inline arguments. Default is 10.
- USERTYPES/A/S,TYPES/M
USERTYPES indicates, that this line contains user defined types
TYPES defines words to treat as basic types like int or long etc.
AUTHOR
Stefan Ruppert
Windthorststrasse 5
65439 Floersheim am Main
Germany
EMail: ruppert@@vs3.informatik.fh-wiesbaden.de
SEE ALSO
text.datatype
*****************************************************************************/
/*FE*/
/*FS*/ /*"Definitions"*/
/* ------------------------------- defines -------------------------------- */
#define PUDDLE_SIZE 2048
#define G(o) ((struct Gadget *) (o))
#define BUFFER_SIZE 1024
#define EOS '\0'
/* ------------------------ preference definition ------------------------- */
const STRPTR prefstemplate[] = {
{"CPART/A/K,PEN/N/K,R=RED/N/K,G=GREEN/N/K,B=BLUE/N/K,"
"ITALIC/S,BOLD/S,UNDERLINED/S,TEXT/S" },
{"GLOBAL/S,TABLENGTH/N/K,NONESTEDCOMMENTS/S" D(",DEBUG/S") },
{"INLINEARGS/S,KEYWORD/K/A,PATTERN/K/A,LINES/N/K"},
{"USERTYPES/S,TYPES/M"},
{ NULL }};
D(extern int cdtparse_debug;)
enum
{
TMPLT_CPART,
TMPLT_GLOBAL,
TMPLT_INLINEARGS,
TMPLT_USERTYPES
};
enum
{
CPARTARG_CSECTION,
CPARTARG_PEN,
CPARTARG_RED,
CPARTARG_GREEN,
CPARTARG_BLUE,
CPARTARG_ITALIC,
CPARTARG_BOLD,
CPARTARG_UNDERLINED,
CPARTARG_TEXT,
CPARTARG_MAX
};
enum
{
GLOBALARG_GLOBAL,
GLOBALARG_TABLENGTH,
GLOBALARG_NONESTEDCOMMENTS,
#ifdef DEBUG
GLOBALARG_DEBUG,
#endif
};
enum
{
INLINEARG_INLINE,
INLINEARG_KEYWORD,
INLINEARG_PATTERN,
INLINEARG_LINES
};
enum
{
USRTYPEARG_USERTYPE,
USRTYPEARG_TYPES,
};
const STRPTR cparts[C_MAX] =
{
"STANDARD",
"COMMENT",
"CPP",
"KEYWORD",
"STORAGE",
"TYPES",
"TYPENAME",
"STRING",
"NUMBER"
};
const struct Style defstyle[C_MAX] =
{
{1,0,FS_NORMAL }, /* C_STANDARD */
{1,0,FSF_ITALIC }, /* C_COMMENT */
{1,0,FSF_BOLD | FSF_ITALIC }, /* C_CPP */
{2,0,FSF_BOLD }, /* C_KEYWORD */
{1,0,FSF_UNDERLINED }, /* C_STORAGE */
{1,0,FSF_BOLD }, /* C_TYPES */
{2,0,FS_NORMAL }, /* C_TYPENAME */
{3,0,FS_NORMAL }, /* C_STRING */
{3,0,FSF_BOLD } /* C_NUMBER */
};
/*FE*/
/* ------------------------------ init class ------------------------------ */
/*FS*/ LibCall Class *initClass(REGA6 struct ClassBase *cb)
{
Class *cl;
if((cl = MakeClass(DATATYPENAME,TEXTDTCLASS,NULL,sizeof(struct CData ),0)))
{
cl->cl_Dispatcher.h_Entry = (HOOKFUNC) dispatch;
cl->cl_UserData = (ULONG) cb;
AddClass(cl);
}
return(cl);
}
/*FE*/
/* ------------------------------ read prefs ------------------------------ */
/*FS*/ BOOL readPrefs(struct ClassBase *cb,struct CData *cd,STRPTR file)
{
struct RDArgs *rdargs;
struct RDArgs *args;
BPTR fh;
ENTERING;
if((fh = Open(file,MODE_OLDFILE)))
{
UBYTE buf[256];
ULONG para[CPARTARG_MAX];
LONG i;
DB(("def file %s opened\n",file));
while(FGets(fh,buf,sizeof(buf)))
{
const STRPTR *tmplt = prefstemplate;
ULONG tmpltnr = 0;
BOOL done = FALSE;
DB(("line : %s",buf));
/* skip comment and empty lines, to speed up parsing */
if(buf[0] == ';' || buf[0] == '\n')
continue;
while(*tmplt && !done)
{
if((rdargs = (struct RDArgs *) AllocDosObject(DOS_RDARGS,NULL)))
{
rdargs->RDA_Source.CS_Buffer = buf;
rdargs->RDA_Source.CS_Length = strlen(buf);
for(i=0 ; i < (sizeof(para)/sizeof(LONG)) ; i++)
para[i]=0;
DB(("rdargs at : %lx\n",rdargs));
if((args = ReadArgs(*tmplt,(LONG *) para,rdargs)))
{
DB(("args at %lx\n",args));
switch(tmpltnr)
{
case TMPLT_CPART:
for(i = C_MAX - 1; i >= 0 ; i--)
if(!Stricmp((STRPTR) para[CPARTARG_CSECTION],(STRPTR) cparts[i]))
{
struct Style *style = &cd->cd_CStyle[i];
if(para[CPARTARG_TEXT])
style->Style = (UWORD) ~0;
else
{
if(para[CPARTARG_PEN])
style->FgPen = (UWORD) *((ULONG *) para[CPARTARG_PEN]);
else if(para[CPARTARG_RED] || para[CPARTARG_GREEN] || para[CPARTARG_BLUE])
{
struct PenNode *pen;
if((pen = AllocPooled(cd->cd_Pool,sizeof(struct PenNode))))
{
pen->pn_Section = i;
pen->pn_Pen = -1;
if(para[CPARTARG_RED])
pen->pn_Red = (*((ULONG *) para[CPARTARG_RED])) << 24;
if(para[CPARTARG_GREEN])
pen->pn_Green = (*((ULONG *) para[CPARTARG_GREEN])) << 24;
if(para[CPARTARG_BLUE])
pen->pn_Blue = (*((ULONG *) para[CPARTARG_BLUE])) << 24;
AddTail(&cd->cd_PenList,(struct Node *) pen);
}
}
style->Style = FS_NORMAL;
if(para[CPARTARG_ITALIC])
style->Style |= FSF_ITALIC;
if(para[CPARTARG_BOLD])
style->Style |= FSF_BOLD;
if(para[CPARTARG_UNDERLINED])
style->Style |= FSF_UNDERLINED;
}
}
done = TRUE;
break;
case TMPLT_GLOBAL:
if(para[GLOBALARG_GLOBAL])
{
if(para[GLOBALARG_TABLENGTH])
cd->cd_TabLength = *((ULONG *) para[GLOBALARG_TABLENGTH]);
if(para[GLOBALARG_NONESTEDCOMMENTS])
cd->cd_Flags.Nested = FALSE;
D({
if(para[GLOBALARG_DEBUG])
cdtparse_debug = 1;
bug("yydebug is : %ld\n",cdtparse_debug);
});
done = TRUE;
}
break;
case TMPLT_INLINEARGS:
if(para[INLINEARG_INLINE])
{
cd->cd_Flags.Inline = TRUE;
if(para[INLINEARG_LINES])
cd->cd_Inline.Lines = *((ULONG *) para[INLINEARG_LINES]);
strncpy(cd->cd_Inline.Keyword,(STRPTR) para[INLINEARG_KEYWORD],INLINE_BUFFER);
cd->cd_Inline.Keyword[INLINE_BUFFER-1] = EOS;
strncpy(cd->cd_Inline.Pattern,(STRPTR) para[INLINEARG_PATTERN],INLINE_BUFFER);
cd->cd_Inline.Pattern[INLINE_BUFFER-1] = EOS;
done = TRUE;
}
break;
case TMPLT_USERTYPES:
if(para[USRTYPEARG_USERTYPE] && para[USRTYPEARG_TYPES])
{
struct Node *node;
STRPTR *types = (STRPTR *) para[USRTYPEARG_TYPES];
while(*types)
{
DB(("usertype : %s\n",*types));
if((node = AllocPooled(cd->cd_Pool,sizeof(struct Node) + strlen(*types) + 1)))
{
node->ln_Name = (STRPTR) (node + 1);
strcpy(node->ln_Name,*types);
node->ln_Type = strlen(node->ln_Name);
AddTail(&cd->cd_UserTypes,node);
}
types++;
}
done = TRUE;
}
break;
}
}
FreeDosObject(DOS_RDARGS , rdargs);
}
tmpltnr++;
tmplt++;
}
}
Close(fh);
}
LEAVING;
return((BOOL) (fh == NULL));
}
/*FE*/
/* ---------------------------- notify object ----------------------------- */
/*FS*/ ULONG notifyAttrChanges(Object * o, void * ginfo, ULONG flags, ULONG tag1,...)
{
return(DoMethod(o, OM_NOTIFY, &tag1, ginfo, flags));
}
/*FE*/
/* --------------------------- class dispatcher --------------------------- */
/*FS*/ ClassCall ULONG dispatch(REGA0 Class *cl,REGA2 Object *obj,REGA1 Msg msg)
{
struct ClassBase *cb = (struct ClassBase *) cl->cl_UserData;
struct CData *cd = INST_DATA(cl,obj);
ULONG retval;
switch(msg->MethodID)
{
case OM_NEW:
{
Object *newobj;
if((newobj = (Object *) DoSuperMethodA(cl,obj,msg)))
{
cd = INST_DATA(cl,newobj);
NewList(&cd->cd_PenList);
NewList(&cd->cd_UserTypes);
cd->cd_TabLength = 8;
cd->cd_Flags.Nested = TRUE;
cd->cd_Inline.Lines = 10;
if((cd->cd_Pool = CreatePool(MEMF_CLEAR | MEMF_ANY , PUDDLE_SIZE,PUDDLE_SIZE)))
{
STRPTR buffer = NULL;
ULONG bufferlen = 0;
if(GetDTAttrs(newobj,TDTA_Buffer ,&buffer,
TDTA_BufferLen ,&bufferlen,
TAG_DONE) == 2 && buffer && bufferlen)
{
int i;
for(i = 0 ; i < C_MAX ; i++)
cd->cd_CStyle[i] = defstyle[i];
for(i = 0 ; i < sizeof(cd->cd_TabBuffer) ; i++)
cd->cd_TabBuffer[i] = ' ';
if(readPrefs(cb,cd,"PROGDIR:Prefs/DataTypes/c.prefs"))
readPrefs(cb,cd,"Env:DataTypes/c.prefs");
if(cd->cd_Flags.Inline)
{
STRPTR ptr = buffer;
STRPTR end = buffer + bufferlen;
STRPTR pat = cd->cd_Inline.Pattern;
ULONG lines = cd->cd_Inline.Lines;
ULONG kwlen = strlen(cd->cd_Inline.Keyword);
while(lines > 0 && ptr < end)
{
if(*ptr == '\n')
lines--;
else if(*ptr == cd->cd_Inline.Keyword[0] &&
!strncmp(cd->cd_Inline.Keyword,ptr,kwlen))
{
ptr += kwlen;
do
{
if(*pat == '%')
{
pat++;
switch(*pat)
{
case 't':
{
LONG num,value;
if((num = StrToLong(ptr,&value)) > 0)
{
cd->cd_TabLength = value;
ptr += num;
}
}
break;
case 'c':
if(!Strnicmp(ptr,"NESTEDCOMMENTS",14))
{
ptr += 14;
cd->cd_Flags.Nested = TRUE;
} else if(!Strnicmp(ptr,"NONESTEDCOMMENTS",16))
{
ptr +=16;
cd->cd_Flags.Nested = FALSE;
}
break;
}
pat++;
}
} while(*ptr !='\n' && *ptr++ == *pat++);
break;
}
ptr++;
}
}
retval = (ULONG) newobj;
} else
SetIoErr(ERROR_REQUIRED_ARG_MISSING);
}
}
if(!retval)
{
D(bug("c.datatype error : %ld\n",IoErr()));
CoerceMethod(cl,(Object *) retval,OM_DISPOSE);
}
}
break;
case OM_DISPOSE:
{
struct List *linelist;
struct PenNode *pen;
if(GetDTAttrs(obj,TDTA_LineList,&linelist,TAG_DONE) && linelist)
NewList(linelist);
while((pen = (struct PenNode *) RemHead(&cd->cd_PenList)))
if(pen->pn_Pen != -1)
ReleasePen(cd->cd_ColorMap,pen->pn_Pen);
if(cd->cd_Pool)
DeletePool(cd->cd_Pool);
retval = DoSuperMethodA(cl,obj,msg);
}
break;
case OM_SET:
case OM_UPDATE:
/* Pass the attributes to the super class and force a refresh
* if we need it */
if((retval = DoSuperMethodA (cl, obj, msg)) && (OCLASS (obj) == cl))
{
struct RastPort *rp;
/* Get a pointer to the rastport */
if((rp = ObtainGIRPort (((struct opSet *) msg)->ops_GInfo)))
{
struct gpRender gpr;
/* Force a redraw */
gpr.MethodID = GM_RENDER;
gpr.gpr_GInfo = ((struct opSet *) msg)->ops_GInfo;
gpr.gpr_RPort = rp;
gpr.gpr_Redraw = GREDRAW_UPDATE;
DoMethodA (obj, (Msg) &gpr);
/* Release the temporary rastport */
ReleaseGIRPort (rp);
}
}
break;
case GM_LAYOUT:
/* Tell everyone that we are busy doing things */
notifyAttrChanges (obj, ((struct gpLayout *) msg)->gpl_GInfo, NULL,
GA_ID, G(obj)->GadgetID,
DTA_Busy, TRUE,
TAG_DONE);
/* Let the super-class partake */
retval = DoSuperMethodA (cl, obj, msg);
/* We need to do this one asynchronously */
retval += DoAsyncLayout (obj, (struct gpLayout *) msg);
break;
case DTM_PROCLAYOUT:
/* Tell everyone that we are busy doing things */
notifyAttrChanges (obj, ((struct gpLayout *) msg)->gpl_GInfo, NULL,
GA_ID, G(obj)->GadgetID,
DTA_Busy, TRUE,
TAG_DONE);
/* Let the super-class partake and then fall through to our layout method */
DoSuperMethodA (cl, obj, msg);
case DTM_ASYNCLAYOUT:
/* Layout the text */
retval = layout(cb, cl, obj, (struct gpLayout *) msg);
break;
default:
retval = DoSuperMethodA(cl,obj,msg);
}
return(retval);
}
/*FE*/
/*FS*/ GetA4 ULONG layout(struct ClassBase *cb, Class * cl, Object * obj, struct gpLayout * gpl)
{
struct DTSpecialInfo *si = (struct DTSpecialInfo *) G(obj)->SpecialInfo;
struct CData *cd = INST_DATA(cl,obj);
struct CParse cparse;
struct RastPort trp;
ULONG visible;
ULONG hunit;
ULONG total = 0;
ULONG bsig = 0;
/* Attributes obtained from super-class */
struct TextAttr *tattr;
struct TextFont *font;
struct List *linelist;
ULONG bufferlen;
STRPTR buffer;
struct IBox *domain;
STRPTR title;
D(bug("layout !\n"));
/* Get all the attributes that we are going to need for a successful layout */
if(GetDTAttrs(obj,DTA_TextFont, (ULONG) &font,
DTA_TextAttr, (ULONG) &tattr,
DTA_Domain, (ULONG) &domain,
DTA_ObjName, (ULONG) &title,
TDTA_LineList, (ULONG) &linelist,
TDTA_Buffer, (ULONG) &buffer,
TDTA_BufferLen,(ULONG) &bufferlen,
TAG_DONE) == 7)
{
ULONG maxwidth = 0;
/* Lock the global object data so that nobody else can manipulate it */
ObtainSemaphore (&(si->si_Lock));
/* Make sure we have a buffer */
if(buffer)
{
/* Initialize the temporary RastPort */
InitRastPort (&trp);
SetFont (&trp, font);
/* We only need to perform layout if we are doing word wrap, or this
* is the initial layout call */
if (gpl->gpl_Initial)
{
struct PenNode *pen;
if((cd->cd_ColorMap = gpl->gpl_GInfo->gi_Screen->ViewPort.ColorMap))
{
for(pen = (struct PenNode *) cd->cd_PenList.lh_Head ;
pen->pn_Node.mln_Succ ;
pen = (struct PenNode *) pen->pn_Node.mln_Succ)
{
pen->pn_Pen = ObtainBestPen(cd->cd_ColorMap,
pen->pn_Red,pen->pn_Green,pen->pn_Blue,
OBP_Precision , PRECISION_ICON,
TAG_DONE);
DB(("pen : %ld allocated for section %ld with RGB : %lx %lx %lx\n",
pen->pn_Pen,pen->pn_Section,pen->pn_Red,pen->pn_Green,pen->pn_Blue));
if(pen->pn_Pen > 0)
cd->cd_CStyle[pen->pn_Section].FgPen = pen->pn_Pen;
else
cd->cd_CStyle[pen->pn_Section].FgPen = 1;
}
}
cparse.BegPtr = buffer;
cparse.ActPtr = buffer;
cparse.TxtPtr = buffer;
cparse.SegPtr = buffer;
cparse.EndPtr = buffer + bufferlen;
cparse.TabWidth = TextLength(&trp," ",1);
cparse.Mode = C_STANDARD;
cparse.XOffset = 0;
cparse.YOffset = 0;
cparse.MaxWidth = 0;
cparse.LineList = linelist;
cparse.RPort = &trp;
cparse.Data = cd;
D({ BPTR fh;
BPTR oldfh;
if(cdtparse_debug)
if((fh = Open("CON:////C-DataType YYDebug/WAIT/CLOSE",MODE_NEWFILE)))
oldfh = SelectOutput(fh);
);
cdtparse_parse(cb,&cparse);
cdtparse_free(cb,&cparse);
D( if(fh && cdtparse_debug)
{
SelectOutput(oldfh);
Close(fh);
}
}
);
total = cparse.YOffset / font->tf_YSize;
maxwidth = cparse.MaxWidth;
}
else
{
/* No layout to perform */
total = si->si_TotVert;
maxwidth = si->si_TotHoriz;
}
}
/* Compute the lines and columns type information */
si->si_VertUnit = font->tf_YSize;
si->si_VisVert = visible = domain->Height / si->si_VertUnit;
si->si_TotVert = total;
si->si_HorizUnit = hunit = font->tf_XSize;
si->si_VisHoriz = (LONG) domain->Width / hunit;
si->si_TotHoriz = maxwidth / hunit;
/* Release the global data lock */
ReleaseSemaphore(&si->si_Lock);
/* Were we aborted? */
if (bsig == 0)
{
/* Not aborted, so tell the world of our newest attributes */
notifyAttrChanges (obj, gpl->gpl_GInfo, NULL,
GA_ID, G(obj)->GadgetID,
DTA_VisibleVert, visible,
DTA_TotalVert, total,
DTA_NominalVert, font->tf_YSize * 25,
DTA_VertUnit, font->tf_YSize,
DTA_VisibleHoriz, (ULONG) (domain->Width / hunit),
DTA_TotalHoriz, maxwidth / hunit,
DTA_NominalHoriz, font->tf_XSize * 80,
DTA_HorizUnit, hunit,
DTA_Title, title,
DTA_Busy, FALSE,
DTA_Sync, TRUE,
TAG_DONE);
}
}
return(total);
}
/*FE*/
@
39.6
log
@*** empty log message ***
@
text
@d4 1
a4 1
** $VER: dispatch.c 39.6 (10.05.95)
d15 1
d437 3
@